package com.blue.user.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blue.common.exception.BizIllegalException;
import com.blue.common.utils.RandomUtils;
import com.blue.common.utils.VerificationCodeGenerator;
import com.blue.starter.cache.RedisCache;
import com.blue.starter.cache.RedisKeys;
import com.blue.starter.core.AjaxResult;
import com.blue.starter.pojo.user.domian.LitUserInfo;
import com.blue.starter.pojo.user.dto.LitUserInfoDto;
import com.blue.user.mapper.LitUserInfoMapper;
import com.blue.user.service.ILitUserInfoService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author : CaiYang
 * @Date : 2025-03-21 15:19
 * @Description :
 */
@Service
@AllArgsConstructor
public class LitUserInfoServiceImpl extends ServiceImpl<LitUserInfoMapper, LitUserInfo> implements ILitUserInfoService {

    private final LitUserInfoMapper litUserInfoMapper;

    private final RedisCache redisCache;

    /**
     * 加载密钥
     */
    @PostConstruct
    private void initAuthKey() {
        String pbk = this.redisCache.getCacheObject(RedisKeys.PUBLIC_KEY);
        String prk = this.redisCache.getCacheObject(RedisKeys.PRIVATE_KEY);
        if (pbk != null && prk != null) {
            return;
        }
        try {
            //sa-token 生成密钥
            HashMap<String, String> map = SaSecureUtil.rsaGenerateKeyPair();
            String publicKey = map.get("public").toString();
            String privateKey = map.get("private").toString();
            this.redisCache.setCacheObject(RedisKeys.PUBLIC_KEY, publicKey);
            this.redisCache.setCacheObject(RedisKeys.PRIVATE_KEY, privateKey);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 生成验证码接口
     *
     * @param phone
     * @return
     */
    @Override
    public AjaxResult genPhoneCode(String phone) {
        //生成随机6位验证码
        String code = VerificationCodeGenerator.generateVerificationCode();
        this.redisCache.setCacheObject(phone, code, 5, TimeUnit.MINUTES);
        return new AjaxResult("短信发送成功", "200");
    }

    /**
     * 用户登录接口
     *
     * @param litUserInfoDto
     * @return
     */
    @Override
    public AjaxResult loginUser(LitUserInfoDto litUserInfoDto) {
        //获取登录方式
        String loginMethod = litUserInfoDto.getLoginMethod();
        LitUserInfo litUserInfo = null;
        //账号密码登录
        if ("0".equals(loginMethod)) {
            String userName = litUserInfoDto.getUserName();
            String passWord = litUserInfoDto.getPassWord();
            LambdaQueryWrapper<LitUserInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LitUserInfo::getUserName, userName);
            litUserInfo = this.baseMapper.selectOne(queryWrapper);
            if (litUserInfo == null) {
                throw new BizIllegalException("用户不存在");
            }
            //加密后的密码
            String pass = litUserInfo.getPass();
            String privateKey = this.redisCache.getCacheObject(RedisKeys.PRIVATE_KEY);
            //解析明文
            String authPass = SaSecureUtil.rsaDecryptByPrivate(privateKey, pass);
            if (authPass.equals(passWord)) {
                throw new BizIllegalException("密码错误");
            }
        }
        //验证码登录
        if ("1".equals(loginMethod)) {
            String code = litUserInfoDto.getCode();
            String phoneNumber = litUserInfoDto.getPhoneNumber();
            String storeCode = this.redisCache.getCacheObject(phoneNumber);
            if (storeCode == null || !storeCode.equals(code)) {
                throw new BizIllegalException("验证码错误");
            }
            //业务查询
            LambdaQueryWrapper<LitUserInfo> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(LitUserInfo::getPhoneNumber, phoneNumber);
            litUserInfo = this.baseMapper.selectOne(queryWrapper);
            //为新用户
            if (litUserInfo == null) {
                litUserInfo = new LitUserInfo();
                litUserInfo.setBackImg("http://101.43.99.167:9000/blue-oss/1684082113-origin-7301FA2F-E003-4AF6-8440-79D7FEEA9B45.jpg");
                litUserInfo.setPersonDes("当前用户太过于优秀，就先不介绍啦");
                litUserInfo.setPhoneNumber(phoneNumber);
                litUserInfo.setUniversity("清华大学");
                litUserInfo.setBirthday("1998-10-01");
                litUserInfo.setBlueCode("CODE" + RandomUtils.generateRandomUsername());
                litUserInfo.setNickName("NO" + RandomUtils.generateRandomUsername());
                litUserInfo.setAvatar("http://101.43.99.167:9000/blue-oss/dog.png");
                litUserInfo.setUserName(RandomUtils.generateRandomUsername());
                //生成随机的密码
                String password = RandomUtils.generateRandomPassword();
                String authPass = this.securityCodePass(password);
                litUserInfo.setPass(authPass);
                litUserInfo.setCreateTime(new Date());
                litUserInfo.setCreateBy(litUserInfo.getNickName());
                this.baseMapper.insert(litUserInfo);
            }
            //短信已经被消费了，移除缓存
            this.redisCache.deleteObject(phoneNumber);
        }
        if("2".equals(loginMethod)){

        }
        StpUtil.login(litUserInfo.getId());
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
        HashMap<String,Object> map = new HashMap<>();
        map.put("token",tokenInfo);
        map.put("userInfo",litUserInfo);
        return new AjaxResult("登录成功","200",map);
    }


    private String securityCodePass(String pass) {
        String publicKey = this.redisCache.getCacheObject(RedisKeys.PUBLIC_KEY);
        return SaSecureUtil.rsaEncryptByPublic(publicKey, pass);
    }
}
